// Copyright 1998-2016 Glenn McIntosh
// licensed under the GNU General Public Licence version 3
#pragma once

/** @file crc.h
	Cyclic redundancy checks.
	*/
// include files
#include <cstdint>

namespace math
{
// definitions

//! Number of bits.
#define CRCBITS 16 // xmodem,X.25,CCITT,BISYNC
// #define CRCBITS 32 // AUTODIN II

//! Size of a CRC word.
#if CRCBITS == 16
typedef uint16_t CrcWord;
#endif
#if CRCBITS == 32
typedef uint32_t CrcWord;
#endif

//! Uses a preinitialized CRC table.
#define PREINIT

/** Cyclic redundancy check. */
class Crc
{
public:
#	ifndef PREINIT
	/** Initialize CRC table.
		*/
	static void initialize();
#	endif

	/** Create checksum.
		*/
	Crc();

	/** Set checksum.
		@param checksum new value
		*/
	Crc &operator=(CrcWord checksum)
	{
		mChecksum = checksum;
		return *this;
	}

	/** Get checksum.
		@return current checksum
		*/
	operator CrcWord()
	{
		return mChecksum;
	}

	/** Supply another character to the checksum.
		@param c character
		*/

	Crc &operator+=(const uint8_t c);
	/** Supply a string to the checksum.
		@param buffer zero terminated string
		*/
	Crc &operator+=(const uint8_t *buffer);

private:
	CrcWord mChecksum;
	static CrcWord mCrcTable[256];
};
}
